package cvm

import (
	"context"

	"gitee.com/go-course/go8/projects/devcloud/cmdb/apps/host"
	"github.com/alibabacloud-go/tea/tea"
	"github.com/infraboard/mcube/flowcontrol/tokenbucket"
	"github.com/infraboard/mcube/logger"
	"github.com/infraboard/mcube/logger/zap"
	cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312"
)

type CvmPagerRequest struct {
	PageSize   int64
	PageNumber int64
}

func (req *CvmPagerRequest) Offset() int64 {
	return (req.PageNumber - 1) * req.PageSize
}

func NewCvmPager(op *CVMOperator, args *CvmPagerRequest) *CvmPager {
	req := cvm.NewDescribeInstancesRequest()
	req.Limit = &args.PageSize

	offset := args.Offset()
	req.Offset = &offset

	return &CvmPager{
		// 默认是由下一页的
		hasNext: true,
		op:      op,
		req:     req,
		log:     zap.L().Named("pager.cvm"),
		tb:      tokenbucket.NewBucketWithRate(0.1, 1),
	}
}

// 跟web界面逻辑一页
// 1. 从第一页开始查询, 100
// 2. 一直点Next(下一页)? 什么时候就结束了，没有下一页了喃?
//   2.1  req.page_number+1
// 3.
// 	3.1. 根据Total 和当前已经的offset进行比较, 需要云商返回的Total要准确
//  3.2. 根据当前页是否满了， 比如一页20  0-19(代表没有下一页)
type CvmPager struct {
	op      *CVMOperator
	req     *cvm.DescribeInstancesRequest
	log     logger.Logger
	tb      *tokenbucket.Bucket
	hasNext bool
}

// 判断是否由下一页
func (c *CvmPager) Next() bool {

	if c.hasNext {
		c.tb.Wait(1)
		return true
	}
	// 等待知道有多个令牌可用,直接取出
	// time.Sleep(1 * time.Second)
	return false
}

// 请求该页的数据
func (c *CvmPager) Scan(ctx context.Context, set *host.HostSet) error {
	resp, err := c.op.QueryCvm(ctx, c.req)
	if err != nil {
		return err
	}
	set.Items = resp.Items

	// 修正Next的结果
	c.log.Debugf("resp length: %d, page size: %d", resp.Length(), tea.Int64Value(c.req.Limit))
	if resp.Length() < int(tea.Int64Value(c.req.Limit)) {
		c.hasNext = false
	} else {
		// 调整到下一页
		offset := tea.Int64Value(c.req.Offset) + tea.Int64Value(c.req.Limit)
		c.req.Offset = &offset
		c.hasNext = true
	}

	return nil
}
